package pl.edu.mimuw.mas.agent.behaviour.hunting.grouping;

import jade.core.AID;
import jade.core.behaviours.OneShotBehaviour;
import jade.core.behaviours.SequentialBehaviour;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jade.lang.acl.UnreadableException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import pl.edu.mimuw.mas.agent.HuntingAgent;
import pl.edu.mimuw.mas.agent.behaviour.ReplyWaitingBehaviour;
import pl.edu.mimuw.mas.message.CharismaMessage;
import pl.edu.mimuw.mas.message.PositionMessage;
import pl.edu.mimuw.mas.util.Time;

public class CharismaUpdateBehaviour extends SequentialBehaviour {

	private static final long serialVersionUID = 3283995116318323373L;
	
	protected final Logger logger = LoggerFactory.getLogger(getClass());
	
	private List<ACLMessage> replies = new ArrayList<ACLMessage>();
	
	public CharismaUpdateBehaviour(HuntingAgent a) {
		super(a);
		
		// prosze o podanie charyzmy
		addSubBehaviour(new OneShotBehaviour(a) {
			
			private static final long serialVersionUID = -2108784139753140534L;

			public void action() {
				HuntingAgent a = (HuntingAgent) myAgent;
				ACLMessage request = new ACLMessage(ACLMessage.REQUEST);
				
				try {
					request.setContentObject(new PositionMessage(a.getAID(), a.getPosition().x, a.getPosition().y));
					request.setConversationId(HuntingAgent.CHARISMA_CONV);
					request.setReplyWith(HuntingAgent.CHARISMA_CONV + System.currentTimeMillis());
				} catch (IOException e) {
					logger.error("{} : błąd podczas serializacji wiadomości", a.getName(), e);
				}
				
				DFAgentDescription template = new DFAgentDescription();
		  		ServiceDescription sd = new ServiceDescription();
		  		sd.setType(a.getServiceType());
		  		template.addServices(sd);
		  		  		
				try {
					DFAgentDescription[] results = DFService.search(a, template);
					for (int i = 0; i < results.length; i++) {
			  			request.addReceiver(results[i].getName());
			  		}
				} catch (FIPAException e) {
					logger.error("{} : błąd FIPA", a.getName(), e);
				}
				
				a.send(request);
			}
		});
		
		// czekam na odpowiedzi
		MessageTemplate mt = MessageTemplate.and(
				MessageTemplate.MatchConversationId(HuntingAgent.CHARISMA_CONV),
				MessageTemplate.MatchPerformative(ACLMessage.INFORM));
		addSubBehaviour(new ReplyWaitingBehaviour(a, mt, Time.MESSAGE_REPLY_WAIT, replies));
		
		// aktualizuje charyzme
		addSubBehaviour(new OneShotBehaviour(a) {

			private static final long serialVersionUID = 1L;

			@Override
			public void action() {
				HuntingAgent a = (HuntingAgent) myAgent;
				a.getCharismaCache().clear();
				CharismaMessage cm;
				for (ACLMessage reply : replies) {
					try {
						cm = (CharismaMessage) reply.getContentObject();
						AID aid = reply.getSender();
						a.getCharismaCache().put(aid, cm.charisma);
					} catch (UnreadableException e) {
						logger.error("{} : UnreadableException {}", a.getName(), e);
					}
				}
			}
		});
	}

}
